<?php
declare(strict_types = 1);

namespace IMOcean\Server\Coroutine;

use Swoole\Coroutine;
use Swoole\Coroutine\Scheduler;
use IMOcean\Closure\Closure;
use IMOcean\Closure\ClosureList;

/**
 * Class Swoole
 * @package IMOcean\Servers
 */
final class Swoole
{
    /**
     * start a coroutine
     *
     * @param Closure $closure
     * @return bool
     */
    public static function execute(Closure $closure)
    {
        $scheduler = new Scheduler();

        $scheduler->add($closure->getClosure(), ...$closure->getArgs());

        return $scheduler->start();
    }

    /**
     * start multiple coroutine
     *
     * @param ClosureList $closureList
     * @return bool
     */
    public static function executeMultiple(ClosureList $closureList): bool
    {
        $scheduler = new Scheduler();

        $element = $closureList->shift();
        while (!is_null($element)) {
            $scheduler->add($element->getClosure(), ...$element->getArgs());

            $element = $closureList->shift();
        }

        return $scheduler->start();
    }

    /**
     * turn on multiple coroutine and execute them concurrently
     *
     * @param ClosureList $closureList
     * @return bool
     */
    public static function executeMultipleSynchronization(ClosureList $closureList): bool
    {
        $scheduler = new Scheduler();

        $scheduler->add(function () use ($closureList) {
            $element = $closureList->shift();
            while (!is_null($element)) {
                Coroutine::create($element->getClosure(), ...$element->getArgs());

                $element = $closureList->shift();
            }
        });

        return $scheduler->start();
    }
}
